import numpy as np
from scipy.spatial import ConvexHull


def calculate_convex_hull_area(x_data, y_data):
    """
    Calculate convex hull area from x and y coordinates.
    This function is equivalent to MATLAB's convhull + polyarea combination.
    
    Args:
        x_data (array-like): X coordinates
        y_data (array-like): Y coordinates
        
    Returns:
        float: Area of the convex hull, or 0.0 if calculation fails
    """
    if len(x_data) < 3:
        return 0.0
    if len(set(x_data)) == 1:  # All x coordinates are the same
        print(f"Degenerate data: all x coordinates are identical ({x_data[0]}), cannot calculate convex hull")
        return 0.0
    if len(set(y_data)) == 1:  # All y coordinates are the same
        print(f"Degenerate data: all y coordinates are identical ({y_data[0]}), cannot calculate convex hull")
        return 0.0
    if len(set(zip(x_data, y_data))) == 1:
        print("Degenerate data: all points are identical, cannot calculate convex hull")
        return 0.0
    
    try:
        # k = convhull(x, y)
        points = np.column_stack((x_data, y_data))
        hull = ConvexHull(points)
        hull_vertices = hull.vertices
        # polyarea(x(k), y(k))
        x_hull = [x_data[int(i)] for i in hull_vertices]
        y_hull = [y_data[int(i)] for i in hull_vertices]
        return polyarea(x_hull, y_hull)
    except Exception as e:
        error_msg = str(e)
        if "qhull input error" in error_msg or "less than 2-dimensional" in error_msg:
            print(f"QHull degenerate data error, skipping convex hull calculation: {error_msg}")
            return 0.0
        else:
            print(f"Convex hull calculation failed, using simplified version: {e}")
            return 0.0

def polyarea(x, y):
    """
    Calculate the area of a polygon using the shoelace formula.
    This is equivalent to MATLAB's polyarea function.
    
    Args:
        x (array-like): X coordinates of polygon vertices
        y (array-like): Y coordinates of polygon vertices
        
    Returns:
        float: Area of the polygon
    """
    x = np.array(x)
    y = np.array(y)
    
    if len(x) != len(y):
        raise ValueError("x and y must have the same length")
    
    if len(x) < 3:
        return 0.0
    
    # Shoelace formula A = 0.5 * |sum(x[i]*y[i+1] - x[i+1]*y[i])|
    n = len(x)
    area = 0.0
    for i in range(n):
        j = (i + 1) % n
        area += x[i] * y[j]
        area -= x[j] * y[i]
    
    return abs(area) / 2.0

